#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
day 35 homework
"""
# 2.多线程实现一个并发的socket server
"""
from socket import socket
from threading import Thread


def socket_pcs(conn):
    msg = conn.recv(1024).decode('utf-8')
    print(msg)
    conn.send(msg.upper().encode('utf-8'))
    conn.close()



if __name__ == '__main__':
    sk = socket()
    sk.bind(('127.0.0.1', 9000))
    sk.listen()
    while True:
        conn, addr = sk.accept()
        Thread(target=socket_pcs, args=(conn,)).start()
"""

# 3.使用多线程 实现一个请求网页 并且把网页写到文件中
# 生产者消费者模型来完成
"""
import requests
from queue import Queue
from threading import Thread


def consumer(q):
    while True:
        ret = q.get()
        print(ret)
        if not ret:
            break
        ret = ret.text
        with open('a.txt', 'a', encoding='utf-8') as f:
            f.write(ret)



def producer(q):
    ret = requests.get(url_lst.pop())
    q.put(ret)
    print(1)


url_lst = [
    'http://www.baidu.com',
    'http://www.cnblogs.com',
    'http://www.douban.com',
    'http://www.tencent.com',
    'http://www.cnblogs.com/Eva-J/articles/8306047.html',
    'http://www.cnblogs.com/Eva-J/articles/7206498.html',
]
if __name__ == '__main__':
    q = Queue(3)
    t_l = list()
    for i in range(5):
        t = Thread(target=producer, args=(q,))
        t.start()
        t_l.append(t)
    for i in range(3):
        t_c = Thread(target=consumer, args=(q,))
        t_c.start()
    for t in t_l:
        t.join()
    for j in range(3):
        q.put(None)
"""

# 6.使用线程池，随意访问n个网址，并把网页内容记录在文件中
"""
import requests
from concurrent.futures import ThreadPoolExecutor

def file_add(t):
    ret = t.result()
    ret = ret.text
    with open('a1.txt', 'a', encoding='utf-8') as f:
        f.write(ret)


def func(url):
    ret = requests.get(url)
    return ret


if __name__ == '__main__':
    url_lst = [
        'http://www.baidu.com',  # 3
        'http://www.cnblogs.com',  # 1
        'http://www.douban.com',  # 1
        'http://www.tencent.com',
        'http://www.cnblogs.com/Eva-J/articles/8306047.html',
        'http://www.cnblogs.com/Eva-J/articles/7206498.html',
    ]
    tp = ThreadPoolExecutor(3)
    for url in url_lst:
        t = tp.submit(func, url)
        t.add_done_callback(file_add)
"""
# 7.请简述什么是死锁现象？如何产生？如何解决
"""
死锁是两个进程各自占用对方等待的信息形成的阻塞。
可以将两个锁修改成同一个递归锁。
"""
# 8.请说说你知道的并发编程中的哪些锁？各有什么特点？
"""
互斥锁：互斥锁在python中不能被连续acquire
递归锁：递归锁在python中可以被连续acquire
"""
# 9.cpython解释器下的线程是否数据安全？
"""
线程在操作全局变量时数据不安全
+= -= *= /= 时数据也不安全
"""
# 10.尝试：在多进程中开启多线程。在进程池中开启线程池
"""
import os
import time
import random
from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor
def func(p, t):
    return '%s %s %s' % (os.getpid(), p, t)


def parserpage(ret):
    print(ret.result())


def pcs(p):
    tp = ThreadPoolExecutor(10)
    for i in range(1, 21):
        time.sleep(random.random())
        ret = tp.submit(func, p, i)
        ret.add_done_callback(parserpage)


if __name__ == '__main__':
    p = ProcessPoolExecutor(5)
    t1 = time.time()
    for i in range(1, 6):
        ret = p.submit(pcs, i)
    p.shutdown()
"""
